﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Reflection;
using System.IO;
using Av;
using System.Threading;

namespace SiteGrabber
{
    public partial class Form1 : Form
    {

        /// <summary>
        /// Systray icon
        /// </summary>
        protected NotifyIcon m_icon = null;

        #region " Get/set text methods (invoked) "

        delegate void SetTextDelegate(string name, string value);
        delegate string GetTextDelegate(string name);

        /// <summary>
        /// Returns text of control.
        /// </summary>
        /// <param name="name">Name of control</param>
        /// <returns>Text of control. Returns "checked"/"" or "" for CheckBox</returns>
        private string GetText(string name)
        {
            string s = "";

            try
            {
                if( this.InvokeRequired )
                {
                    this.Invoke(new GetTextDelegate(GetText), name);
                } else
                {
                    Control[] ar = this.Controls.Find(name, false);
                    if( (ar != null) && (ar.Length > 0) )
                    {
                        if( ar[0].GetType() == typeof(CheckBox) )
                        {
                            s = ((CheckBox)ar[0]).Checked ? "checked" : "";
                        } else
                        {
                            s = ar[0].Text;
                        }
                    }
                }
            } catch( Exception ex )
            {
            }

            return s;
        }

        /// <summary>
        /// Thread safe AddText
        /// </summary>
        /// <param name="name">Name of control to add text</param>
        /// <param name="value">Text to add</param>
        private void AddText(string name, string value)
        {
            try
            {
                if( this.InvokeRequired )
                {
                    this.Invoke(new SetTextDelegate(AddText), name, value);
                } else
                {
                    Control[] ar = this.Controls.Find(name, false);
                    if( (ar != null) && (ar.Length > 0) )
                    {
                        ar[0].Text += value;
                        if( ar[0].GetType() == typeof(TextBox) )
                        {
                            ((TextBox)ar[0]).SelectionStart = Int32.MaxValue;
                        }
                    }
                }
            } catch( Exception )
            {
            }
        }

        /// <summary>
        /// Thread safe SetText
        /// </summary>
        /// <param name="name">Name of control to set text</param>
        /// <param name="value">Text to set</param>
        private void SetText(string name, string value)
        {
            try
            {
                if( this.InvokeRequired )
                {
                    this.Invoke(new SetTextDelegate(SetText), name, value);
                } else
                {
                    Control[] ar = this.Controls.Find(name, false);
                    if( (ar != null) && (ar.Length > 0) )
                    {
                        ar[0].Text = value;
                    }
                }

            } catch( Exception ex )
            {
            }
        }

        #endregion


        public Form1()
        {
            this.Visible = false;
            this.ShowInTaskbar = false;
            this.Opacity = 0;

            InitializeComponent();
        }

        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams cp = base.CreateParams;
                // Turns on WS_EX_TOOLWINDOW style bit to hide from Alt-TAB list
                cp.ExStyle |= 0x80;
                return cp;
            }
        }

        private void OnFormLoaded(object sender, EventArgs e)
        {
            try
            {
                Log4cs.Log("Starting {0} (v{1})...", Settings.Name, Settings.Version);

                bool createdNew = false;
                Mutex mx = new Mutex(false, Settings.Name, out createdNew);
                Log4cs.Log(Importance.Debug, "Is mutex created: {0}", createdNew);

                // If application is already running
                if( createdNew == false )
                {
                    throw new ApplicationException(Settings.Name + " application is already running!");
                }

                this.Text = Settings.NameVersion;

                // Create tray icon
                Assembly asm = Assembly.GetExecutingAssembly();
                FileInfo fi = new FileInfo(asm.GetName().Name);
                using( Stream s = asm.GetManifestResourceStream(string.Format("{0}.av1.ico", fi.Name)) )
                {
                    m_icon = new NotifyIcon();
                    m_icon.Visible = true;
                    m_icon.Icon = new Icon(s);
                }

                // Create context menu for tray icon
                MenuItem[] arMenu = this.CreateMenuItems();
                if( arMenu != null )
                    m_icon.ContextMenu = new ContextMenu(arMenu);

            }catch(ApplicationException ex)
            {
                MessageBox.Show(ex.ToString(), string.Format("{0} (v{1})", Settings.Name, Settings.Version), MessageBoxButtons.OK, MessageBoxIcon.Error);
                this.Close();
            } catch( Exception ex )
            {
                Log4cs.Log(Importance.Error, "Error loading main form!");
                Log4cs.Log(Importance.Debug, ex.ToString());
                MessageBox.Show("Error loading application!", string.Format("{0} (v{1})", Settings.Name, Settings.Version), MessageBoxButtons.OK, MessageBoxIcon.Error);
                this.Close();
            }
        }

        void OnContextMenuClicked(object sender, EventArgs e)
        {
            try
            {
                switch( ((MenuItem)sender).Index )
                {
                    case MyMenu.Position.Start:
                        m_icon.ContextMenu.MenuItems[MyMenu.Position.Start].Enabled = false;
                        m_icon.ContextMenu.MenuItems[MyMenu.Position.Stop].Enabled = true;
                //        OnStartStopClicked(null, null);
                        break;
                    case MyMenu.Position.Stop:
                        m_icon.ContextMenu.MenuItems[MyMenu.Position.Start].Enabled = true;
                        m_icon.ContextMenu.MenuItems[MyMenu.Position.Stop].Enabled = false;
                //        OnStartStopClicked(null, null);
                        break;
                    case MyMenu.Position.Version:
                        MessageBox.Show("Site Status Tracker by mr. Aleksej Vasinov", Settings.NameVersion, MessageBoxButtons.OK, MessageBoxIcon.Information);
                        break;
                    case MyMenu.Position.Reload:
                        ReloadSettings();
                        break;
                    default:
                        this.Close();
                        break;
                }

            } catch( Exception ex )
            {
                Log4cs.Log(Importance.Error, "Error handling context menu click!");
                Log4cs.Log(Importance.Debug, ex.ToString());
            }
        }


        /// <summary>
        /// Creates context menu for tray icon
        /// </summary>
        /// <returns></returns>
        private MenuItem[] CreateMenuItems()
        {
            MenuItem[] arMenu = null;

            try
            {
                // Got quantity of menus
                arMenu = new MenuItem[MyMenu.Size];

                for( int i = 0; i < MyMenu.Size; i++ )
                {
                    arMenu[i] = new MenuItem(MyMenu.ToName(i), OnContextMenuClicked);
                }

                // By default status thread is stopped, so disable "Stop" command
                arMenu[MyMenu.Position.Stop].Enabled = false;

                // Format "Version"
                arMenu[MyMenu.Position.Version].Text = string.Format("{0} (v{1})", Settings.Name, Settings.Version);

            } catch( Exception ex )
            {
                Log4cs.Log(Importance.Error, "Error creating menu items!");
                Log4cs.Log(Importance.Debug, ex.ToString());
            }

            return arMenu;
        }

        /// <summary>
        /// Reloads setting. Stops thread if necessary
        /// </summary>
        private void ReloadSettings()
        {
            Log4cs.Log("Reloading settings...");
            Settings.Load();
        }


    }
}
